# -*- coding: utf-8 -*-

import requests
import rsa
import base64
import bottle
import re
import time
import json
import datetime

app = bottle.Bottle()
session = requests.session()
new = []

@app.route("/login", method="GET")
def login_get():
    if bottle.request.get_cookie("userid", secret="secret-key"):
        userid = bottle.request.get_cookie("userid", secret="secret-key")
        pwd = bottle.request.get_cookie("pwd", secret="secret-key")
    else:
        userid, pwd = "", ""
    return '''
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  <title>帐号登录</title>
  <link rel="stylesheet" href="css/login_style.css">
</head>
<body>
  <section class="container">
    <div class="login">
      <h1>帐号登录</h1>
      <form method="post" action="login">
        <p><input type="text" name="username" value="{userid}" placeholder="哔哩哔哩 帐号"></p>
        <p><input type="password" name="password" value="{pwd}" placeholder="密码"></p>
        <p class="remember_me">
          <label>
            <input type="checkbox" name="remember_me" id="remember_me" checked="True">
            记住帐号
          </label>
        </p>
        <p class="submit"><input type="submit" value="登录"></p>
      </form>
    </div>
  </section>
</body>
</html>'''.format(userid=userid, pwd=pwd)

@app.route("/css/:filename")
def static_css(filename):
    return bottle.static_file(filename, root="static/html/css")

@app.route("/js/:filename")
def static_js(filename):
    return bottle.static_file(filename, root="static/html/js")

def encrypt(pwd):
    global session
    r = session.get("https://passport.bilibili.com/login?act=getkey").json()
    hash = r["hash"]
    key = rsa.PublicKey.load_pkcs1_openssl_pem(r["key"].encode("utf-8"))
    return str(base64.b64encode(rsa.encrypt((hash + pwd).encode("utf-8"), key)))[2:-1]

def LOGIN(userid, pwd, captcha):
    global session
    r = session.post(
        url="https://passport.bilibili.com/ajax/miniLogin/login",
        params={
            "userid": userid,
            "pwd": pwd,
            "captcha": captcha,
            "keep": 1}).json()
    if r["status"]:
        session.get(r["data"]["crossDomain"].replace("bilibili.cn", "im9.com"))
        return session
    else:
        return r["message"]["code"]

@app.route("/login/captcha")
def getcaptcha():
    global session
    LOGIN(bottle.request.GET.get("userid", ""), "", "")
    return session.get("https://passport.bilibili.com/captcha").content

@app.route("/login", method="POST")
def login():
    userid, pwd = bottle.request.forms.get("username"), bottle.request.forms.get("password")
    if bottle.request.forms.get("remember_me"):
        bottle.response.set_cookie("userid", userid, secret="secret-key")
        bottle.response.set_cookie("pwd", pwd, secret="secret-key")
    global session
    return '''
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title>验证码</title>
    <link rel="stylesheet" href="css/login_style.css">
  </head>
  <body>
    <section class="container">
      <div class="login">
      <h1>验证码</h1>
        <form action="login/submit" method="post">
          <center><img width=70% src="./login/captcha?userid={userid}" /></center>
          <p><input type="text" name="captcha" value="" placeholder="验证码" /></p>
          <p style="display: none;"><input name="username" value="{userid}" /><input name="password" value="{password}"></p>
          <p class="submit"><input type="submit" value="登录"></p>
        </form>
      </div>
    </section>
  </body>
</html>'''.format(userid=userid, password=pwd)

@app.route("/login/submit", method="POST")
def login_submit():
    userid = bottle.request.forms.get("username")
    pwd = bottle.request.forms.get("password")
    captcha = bottle.request.forms.get("captcha")
    result = LOGIN(userid, encrypt(pwd), captcha)
    if not isinstance(result,int):
        bottle.redirect("/")
    else:
        return '''<html><script>alert("登录失败：%s");window.location = "../login";</script></html>''' % str(result)

@app.route("/")
def index():
    global session
    info = session.get("http://space.bilibili.com/ajax/member/MyInfo").json()
    if info["status"]:
        bottle.redirect("/main/select")
    else:
        print("\n==========\nPlease sign in first!\n==========\n")
        bottle.redirect("/login")

@app.route("/main/select")
def select_com():
    global session
    captcha = re.search("'(.*?)'", session.get("http://www.im9.com/web/captcha.do").text).group(1)
    r = session.get(
        url="http://www.im9.com/api/manager/query.my.manage.community.list.do",
        params={
            "captcha": captcha,
            "ts":time.time()*1000}).json()
    if r["code"] == 0:
        options = ""
        for com in sorted(r["data"], key=lambda x:x["community_id"], reverse=False):
            options += '<option value="{community_id}">[{community_id}]{community_name}({role})</option>'.format(
                community_id=com["community_id"],
                community_name=com["community_name"],
                role=["神秘人", "成员", "组长", "小组长"][com["role_id"]])
    r = session.get("http://space.bilibili.com/ajax/member/MyInfo").json()
    return '''
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
  <title>选择圈子</title>
  <link rel="stylesheet" href="../css/login_style.css">
</head>
<body>
  <section class="container">
    <div class="login">
      <h1>选择所要管理的圈子</h1>
      <div width=100%><center><img src="{s_face}" width=100px/><br />{username}</center></div>
      <form method="get" action="community">
        <center><select name="community_id">
        {option}
        </select></center>
        <p class="submit"><input type="submit" value="登录"></p>
      </form>
    </div>
  </section>
</body>
</html>'''.format(option=options, username=r["data"]["uname"], s_face=r["data"]["s_face"])

@app.route("/main/community")
@bottle.view("community")
def community():
    global session
    captcha = re.search("'(.*?)'", session.get("http://www.im9.com/web/captcha.do").text).group(1)
    if bottle.request.get_cookie("lastsend", secret="secret-key"):
        lastsend = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime(bottle.request.get_cookie("lastsend", secret="secret-key")))
    else:
        lastsend = "N/A"
    r = session.get(
        url="http://www.im9.com/api/query.detail.community.do",
        params={
            "community_id": bottle.request.GET.get("community_id", ""),
            "captcha": captcha,
            "ts": int(time.time() * 1000)}).json()
    if r["code"] == 0:
        return {
            "community_bg_url": r["data"]["community_bg_url"],
            "community_id": bottle.request.GET.get("community_id"),
            "community_name": r["data"]["name"],
            "community_desc": r["data"]["desc"],
            "newmember_count": r["data"]["member_update"],
            "lastsend": lastsend,
            "user_vue": '<li v-for="user in userlist">{{ user.username }} | 加入时间: {{ user.join_time }}<hr /></li>'
        }

def ifnew(timestr):
    if bottle.request.get_cookie("last_send", secret="secret-key"):
        lastsend = bottle.request.get_cookie("last_send", secret="secret-key")
    else:
        lastsend = int(time.mktime(datetime.date.today().timetuple()))
        bottle.response.set_cookie("last_send", lastsend, secret="secret-key")
    return int(time.mktime(time.strptime(timestr, "%Y-%m-%d %H:%M:%S"))) > lastsend

def getmembers(community_id, page_no):
    captcha = re.search("'(.*?)'", session.get("http://www.im9.com/web/captcha.do").text).group(1)
    r = session.get(
        url="http://www.im9.com/api/manager/query.member.list.do",
        params={
            "captcha": captcha,
            "community_id": community_id,
            "page_no": page_no,
            "page_size": 99,
            "ts": int(time.time()*1000),
            "username": ""}).json()
    if r["code"] == 0:
        users = []
        for user in r["data"]["result"]:
            new = ifnew(user["join_time"])
            if new:
                users.append({"username": user["username"], "member_id": user["member_id"], "join_time": user["join_time"]})
            else:
                break
        if new:
            users += getmembers(community_id, page_no+1)
        #bottle.response.set_cookie("last_send", int(time.time()), secret="secret-key")
        return users
    else:
        print(r)
        exit(1)

@app.route("/main/new.member.get")
def getnewmember():
    global new
    global session
    if new == []:
        new = getmembers(bottle.request.GET.get("community_id"), 1)
    if len(new) % 20 > 0:
        total_page = len(new) // 20 + 1
    else:
        total_page = len(new) // 20
    if len(new) > 20:
        return json.dumps({"result": new[0:21], "total_page": total_page,"count": len(new)}, ensure_ascii=False)
    else:
        return json.dumps({"result": new, "total_page": 1, "count": len(new)}, ensure_ascii=False)

@app.route("/main/memberlist")
def getmember():
    global new
    if len(new) % 20 > 0:
        total_page = len(new) // 20 + 1
    else:
        total_page = len(new) // 20
    if len(new) > 20:
        page_no = int(bottle.request.GET.get("page_no", 1))
        if page_no > total_page:
            return json.dumps({"result": [], "total_page": total_page,"count": len(new)}, ensure_ascii=False)
        elif 20*page_no > len(new):
            return json.dumps({"result": new[20*(page_no-1):], "total_page": total_page,"count": len(new)}, ensure_ascii=False)
        return json.dumps({"result": new[20*(page_no-1) : 20*page_no], "total_page": total_page,"count": len(new)}, ensure_ascii=False)
    else:
        return json.dumps({"result": new, "total_page": 1, "count": len(new)}, ensure_ascii=False)

if __name__ == "__main__":
    app.run(host="0.0.0.0", port=2333)
